
/**
 * Universidad del Valle de Guatemala
 * CC2003 Algoritmos y Estructuras de Datos
 * Proyecto 1: Intérprete de LISP --> Lambda LISP
 * @version 2 Septiembre, 2009
 * Integrantes:
 *      @author Julio Chicas, José García, Ernesto Rodríguez, Karen Tojín
 **/
/**
 * Descripción: Clase auxiliar para la definición de funciones con DEFUN
 **/
import java.util.ArrayList;

public class VarArray {

    private ArrayList<Variable> var = new ArrayList<Variable>(0);

    /**
     * Método que agrega una variable al Array
     * @param nom: Nombre de la variable a agregar
     * @param val: Su valor
     */
    private void adds(String nom, Object val) {
        var.add(new Variable(nom, val));
    }

    /**
     * Método que devuelve el valor de la variable ingresada
     * @param nom: Nombre de la variable de la que se desea el valor
     * @return El valor de la valor si existe
     * @throws NonexistentException
     */
    public Object retVal(String nom) throws NonexistentException {
        return retVar(nom).val();
    }

    /**
     * Método que agrega una variable al Array
     * @param a: La variable a agregar
     */
    private void adds(Variable a) {
        var.add(new Variable(a));
    }

    /**
     * Método que devuelve la variable ingresada
     * @param a: Variable a devolver
     * @return
     */
    public Variable get(int a) {
        return var.get(a);
    }

    /**
     * Método que agrega una variable
     * @param a: Variable a agregar
     */
    public void addExclusive(Variable a) {
        try {
            retVar(a.name());
        } catch (NonexistentException e) {
            adds(a);
        }
    }

    /**
     * Método que agrega una variable
     * @param nom: Nombre de la variable a agregar
     * @param val: Su valor
     */
    public void addExclusive(String nom, Object val) {
        try {
            retVar(nom);
        } catch (NonexistentException e) {
            adds(nom, val);
        }
    }

    /**
     * Método que agrega una variable
     * @param a: Variable a agregar
     */
    public void add(Variable a) {
        try {
            set(a);
        } catch (NonexistentException e) {
            adds(a);
        }
    }

    /**
     * Método que agrega una variable
     * @param nom: Nombre de la variable
     * @param val: Su valor
     */
    public void add(String nom, Object val) {
        try {
            if (retVar(nom).getSettable()) {
                set(nom, val);
            }
        } catch (NonexistentException e) {
            adds(nom, val);
        }
    }

    /**
     * Método que devuelve una variable
     * @param nom: Nombre de la variable que se desea
     * @return La variable si existe
     * @throws NonexistentException
     */
    private Variable retVar(String nom) throws NonexistentException {
        for (int a = 0; a < var.size(); a++) {
            if (var.get(a).eq(nom)) {
                return var.get(a);
            }
        }

        throw new NonexistentException();
    }

    /**
     * Método set para el nombre y el valor de una variable
     * @param nom: Nombre
     * @param val: Su valor
     * @throws NonexistentException
     */
    public void set(String nom, Object val) throws NonexistentException {
        retVar(nom).setVal(val);
    }

    /**
     * Método set para una variable
     * @param a: Variable
     * @throws NonexistentException
     */
    public void set(Variable a) throws NonexistentException {
        retVar(a.name()).setVal(a.val());
    }

    /**
     * Método que devuelvel el tamaño de una variable
     * @return Tamaño de la variable
     */
    public int size() {
        return var.size();
    }
	
/**
     * Método que devuelve el valor de la variable ingresada unicamente si su settable es falso
     * @param nom: Nombre de la variable de la que se desea el valor
     * @return El valor de la valor si existe
     * @throws NonexistentException
     */	
    public Object retVal2(String nom) throws NonexistentException {
        if(!retVar(nom).getSettable())
	    return retVar(nom).val();
	throw new NonexistentException();
    }
}

